This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / routes / [handle] / +page.ts
2.7 kB 86 lines
1import type { Did } from "@atcute/lexicons/syntax"; 2import { createBobbinClient } from "$lib/api/client"; 3import { count } from "$lib/api/count"; 4import { toHttpError } from "$lib/api/load"; 5import { 6 fetchReposPage, 7 fetchStringsPage, 8 fetchStarredPage, 9 fetchPeoplePage, 10 fetchVouchesPage, 11 fetchPinned 12} from "$lib/components/profile/pages"; 13import type { PageLoad } from "./$types"; 14 15const TABS = [ 16 "overview", 17 "repos", 18 "starred", 19 "strings", 20 "followers", 21 "following", 22 "vouches" 23] as const; 24type Tab = (typeof TABS)[number]; 25 26const normalizeTab = (raw: string | null): Tab => 27 TABS.includes(raw as Tab) ? (raw as Tab) : "overview"; 28 29export const load: PageLoad = async (event) => { 30 const parent = await event.parent(); 31 const tab = normalizeTab(event.url.searchParams.get("tab")); 32 33 if (parent.notJoined) return { tab: "overview" as const, overview: { pinned: [] } }; 34 35 const ctx = createBobbinClient({ serviceUrl: parent.publicConfig.bobbinUrl, fetch: event.fetch }); 36 const did = parent.identity.did as Did; 37 const handle = parent.identity.handle; 38 const viewerDid = parent.auth?.did; 39 40 try { 41 switch (tab) { 42 case "repos": { 43 const q = event.url.searchParams.get("q")?.trim(); 44 const page = await fetchReposPage(ctx, { did, handle, viewerDid, q: q || undefined }); 45 return { tab: "repos" as const, repos: page.items, cursor: page.cursor }; 46 } 47 case "strings": { 48 const page = await fetchStringsPage(ctx, { did, handle }); 49 return { tab: "strings" as const, strings: page.items, cursor: page.cursor }; 50 } 51 case "followers": 52 case "following": { 53 const page = await fetchPeoplePage(ctx, { did, viewerDid, direction: tab }); 54 return { tab, people: page.items, cursor: page.cursor } as const; 55 } 56 case "vouches": { 57 const page = await fetchVouchesPage(ctx, { did }); 58 const outgoing = await count(ctx, "sh.tangled.graph.countVouchesBy", did); 59 return { 60 tab: "vouches" as const, 61 vouches: page.items, 62 cursors: page.cursors, 63 vouchTotal: parent.counts.vouches + outgoing.count, 64 isSelf: viewerDid === did, 65 profileHandle: handle 66 }; 67 } 68 case "starred": { 69 const page = await fetchStarredPage(ctx, { did, viewerDid }); 70 return { tab: "starred" as const, stars: page.items, cursor: page.cursor }; 71 } 72 case "overview": 73 default: { 74 const pinned = await fetchPinned(ctx, { 75 keys: parent.profile?.pinnedRepositories ?? [], 76 handle, 77 viewerDid 78 }); 79 return { tab: "overview" as const, overview: { pinned } }; 80 } 81 } 82 } catch (cause) { 83 console.error("Page load error:", cause); 84 toHttpError(cause, "Could not load profile data"); 85 } 86};